package com.ruoyi.course.service.impl;

import com.ruoyi.course.constants.CourseScheduleConstants;
import com.ruoyi.course.domain.CourseSchedule;
import com.ruoyi.course.domain.CourseCla;
import com.ruoyi.course.domain.CourseSwitch;
import com.ruoyi.course.dto.BatchAddScheduleDto;
import com.ruoyi.course.dto.OneClickAddScheduleDto;
import com.ruoyi.course.mapper.CourseLessonMapper;
import com.ruoyi.course.mapper.CourseScheduleMapper;
import com.ruoyi.course.mapper.CourseClaMapper;
import com.ruoyi.course.mapper.CourseSwitchMapper;
import com.ruoyi.course.service.ICourseScheduleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 课程安排Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-06-12
 */
@Service
public class CourseScheduleServiceImpl implements ICourseScheduleService 
{
    @Autowired
    private CourseScheduleMapper courseScheduleMapper;
    
    @Autowired
    private CourseClaMapper courseClaMapper;
    
    @Autowired
    private CourseSwitchMapper courseSwitchMapper;
    
    @Autowired
    private CourseLessonMapper courseLessonMapper;

    /**
     * 获取当前时间字符串，格式：yyyy-MM-dd HH:mm:ss
     */
    private String getCurrentTimeString() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

    /**
     * 查询课程安排
     * 
     * @param scheduleId 课程安排主键
     * @return 课程安排
     */
    @Override
    public CourseSchedule selectCourseScheduleByScheduleId(Long scheduleId)
    {
        return courseScheduleMapper.selectCourseScheduleByScheduleId(scheduleId);
    }

    /**
     * 查询课程安排列表
     * 
     * @param courseSchedule 课程安排
     * @return 课程安排
     */
    @Override
    public List<CourseSchedule> selectCourseScheduleList(CourseSchedule courseSchedule)
    {
        return courseScheduleMapper.selectCourseScheduleList(courseSchedule);
    }

    /**
     * 新增课程安排
     * 
     * @param courseSchedule 课程安排
     * @return 结果
     */
    @Override
    public int insertCourseSchedule(CourseSchedule courseSchedule)
    {
        // 输出调试信息
        System.out.println("=== 手动添加课程调试信息 ===");
        System.out.println("lessonId: " + courseSchedule.getLessonId());
        System.out.println("claId: " + courseSchedule.getClaId());
        System.out.println("scheduleType: " + courseSchedule.getScheduleType());
        System.out.println("specificDate: " + courseSchedule.getSpecificDate());
        System.out.println("timePeriod: " + courseSchedule.getTimePeriod());
        System.out.println("=========================");
        
        // 检查必要参数
        if (courseSchedule.getLessonId() == null) {
            throw new RuntimeException("课程ID不能为空");
        }
        if (courseSchedule.getClaId() == null) {
            throw new RuntimeException("班级ID不能为空");
        }
        
        // 检查课时限制
        if (courseSchedule.getClaId() != null) {
            CourseCla courseCla = courseClaMapper.selectCourseClaByClaId(courseSchedule.getClaId().intValue());
            if (courseCla != null) {
                Long totalClassHours = courseCla.getTotalNum();
                Long passedClassHours = courseCla.getPassNum() != null ? courseCla.getPassNum() : 0L;
                
                if (totalClassHours != null && totalClassHours > 0) {
                    // 获取当前班级的所有课程安排，统计已安排的课时
                    List<CourseSchedule> existingSchedules = courseScheduleMapper.selectCourseScheduleByClaId(courseSchedule.getClaId());
                    long scheduledClassHours = 0;
                    if (existingSchedules != null) {
                        for (CourseSchedule schedule : existingSchedules) {
                            if ("1".equals(schedule.getStatus())) { // 只统计正常状态的课程
                                scheduledClassHours += 1; // 每个课程安排固定1课时
                            }
                        }
                    }
                    
                    long remainingClassHours = totalClassHours - scheduledClassHours;
                    if (remainingClassHours <= 0) {
                        throw new RuntimeException("班级课时已满，无法添加更多课程。总课时:" + totalClassHours + "课时，已安排:" + scheduledClassHours + "课时");
                    }
                    
                    System.out.println("课时检查：总课时=" + totalClassHours + "课时，已安排=" + scheduledClassHours + "课时，剩余=" + remainingClassHours + "课时");
                }
            }
        }
        
        // 为scheduleType为1或2的数据自动设置时间
        String scheduleType = courseSchedule.getScheduleType();
        if ("1".equals(scheduleType) || "2".equals(scheduleType)) {
            String currentTime = getCurrentTimeString();
            courseSchedule.setCreTime(currentTime);
            courseSchedule.setUpdTime(currentTime);
        }
        
        int result = courseScheduleMapper.insertCourseSchedule(courseSchedule);
        System.out.println("手动添加课程结果: " + result + ", 新生成的scheduleId: " + courseSchedule.getScheduleId());
        
        return result;
    }

    /**
     * 修改课程安排
     * 
     * @param courseSchedule 课程安排
     * @return 结果
     */
    @Override
    public int updateCourseSchedule(CourseSchedule courseSchedule)
    {
        // 在更新前记录调课信息
        recordCourseSwitch(courseSchedule);
        
        // 修改时总是更新updTime
        courseSchedule.setUpdTime(getCurrentTimeString());
        
        return courseScheduleMapper.updateCourseSchedule(courseSchedule);
    }

    /**
     * 批量删除课程安排
     * 
     * @param scheduleIds 需要删除的课程安排主键
     * @return 结果
     */
    @Override
    public int deleteCourseScheduleByScheduleIds(Long[] scheduleIds)
    {
        int result = 0;
        for (Long scheduleId : scheduleIds) {
            result += softDeleteCourseSchedule(scheduleId);
        }
        return result;
    }

    /**
     * 删除课程安排信息
     * 
     * @param scheduleId 课程安排主键
     * @return 结果
     */
    @Override
    public int deleteCourseScheduleByScheduleId(Long scheduleId)
    {
        return courseScheduleMapper.deleteCourseScheduleByScheduleId(scheduleId);
    }

    /**
     * 根据班级ID查询课程安排列表
     * 
     * @param claId 班级ID
     * @return 课程安排集合
     */
    @Override
    public List<CourseSchedule> selectCourseScheduleByClaId(Long claId)
    {
        return courseScheduleMapper.selectCourseScheduleByClaId(claId);
    }

    /**
     * 检查时间冲突
     * 
     * @param claId 班级ID
     * @param specificDate 具体日期
     * @param timePeriod 时间段
     * @return 冲突的课程安排集合
     */
    @Override
    public List<CourseSchedule> checkTimeConflict(Long claId, String specificDate, String timePeriod)
    {
        return courseScheduleMapper.checkTimeConflict(claId, specificDate, timePeriod);
    }

    /**
     * 检查模板课程冲突
     * 
     * @param claId 班级ID
     * @param weekDay 星期
     * @param timePeriod 时间段
     * @return 冲突的课程安排集合
     */
    @Override
    public List<CourseSchedule> checkTemplateConflict(Long claId, String weekDay, String timePeriod)
    {
        return courseScheduleMapper.checkTemplateConflict(claId, weekDay, timePeriod);
    }

    /**
     * 批量插入课程安排
     * 
     * @param batchDto 批量添加参数
     * @return 插入的记录数
     */
    @Override
    public int batchInsertCourseSchedule(BatchAddScheduleDto batchDto)
    {
        // 检查课时限制
        if (batchDto.getClaId() != null) {
            CourseCla courseCla = courseClaMapper.selectCourseClaByClaId(batchDto.getClaId().intValue());
            if (courseCla != null) {
                Long totalClassHours = courseCla.getTotalNum();
                Long passedClassHours = courseCla.getPassNum() != null ? courseCla.getPassNum() : 0L;
                
                if (totalClassHours != null && totalClassHours > 0) {
                    // 获取当前班级的所有课程安排，统计已安排的课时
                    List<CourseSchedule> existingSchedules = courseScheduleMapper.selectCourseScheduleByClaId(batchDto.getClaId());
                    long scheduledClassHours = 0;
                    if (existingSchedules != null) {
                        for (CourseSchedule schedule : existingSchedules) {
                            if ("1".equals(schedule.getStatus())) { // 只统计正常状态的课程
                                scheduledClassHours += 1; // 每个课程安排固定1课时
                            }
                        }
                    }
                    
                    long remainingClassHours = totalClassHours - scheduledClassHours;
                    
                    // 解析日期范围，计算要添加的课程数量（每个日期固定1课时）
                    List<String> dateList = parseDateRange(batchDto.getSpecificDate());
                    
                    if (dateList.size() > remainingClassHours) {
                        throw new RuntimeException("要添加的课程数量(" + dateList.size() + "课时)超过剩余课时(" + remainingClassHours + "课时)。总课时:" + totalClassHours + "课时，已安排:" + scheduledClassHours + "课时");
                    }
                    
                    System.out.println("批量添加课时检查：总课时=" + totalClassHours + "课时，已安排=" + scheduledClassHours + "课时，剩余=" + remainingClassHours + "课时，要添加=" + dateList.size() + "课时");
                }
            }
        }
        
        List<CourseSchedule> scheduleList = new ArrayList<>();
        
        // 解析日期范围
        List<String> dateList = parseDateRange(batchDto.getSpecificDate());
        
        for (String date : dateList) {
            CourseSchedule schedule = new CourseSchedule();
            schedule.setLessonId(batchDto.getLessonId());
            schedule.setTimePeriod(batchDto.getTimePeriod());
            schedule.setClaId(batchDto.getClaId());
            schedule.setScheduleType(CourseScheduleConstants.ScheduleType.BATCH_ADD);
            schedule.setSpecificDate(date);
            schedule.setStatus(CourseScheduleConstants.Status.ACTIVE);
            // 设置当前时间
            String currentTime = getCurrentTimeString();
            schedule.setCreTime(currentTime);
            schedule.setUpdTime(currentTime);
            
            scheduleList.add(schedule);
        }
        
        return courseScheduleMapper.batchInsertCourseSchedule(scheduleList);
    }

    /**
     * 解析日期范围，支持单日期和日期范围
     * 
     * @param dateStr 日期字符串，支持 "2025-06-18" 或 "2025-06-18~2025-06-20"
     * @return 日期列表
     */
    private List<String> parseDateRange(String dateStr) {
        List<String> dateList = new ArrayList<>();
        
        if (dateStr == null || dateStr.trim().isEmpty()) {
            return dateList;
        }
        
        try {
            if (dateStr.contains("~")) {
                // 日期范围格式: 2025-06-18~2025-06-20
                String[] dates = dateStr.split("~");
                if (dates.length == 2) {
                    LocalDate startDate = LocalDate.parse(dates[0].trim(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    LocalDate endDate = LocalDate.parse(dates[1].trim(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    
                    LocalDate current = startDate;
                    while (!current.isAfter(endDate)) {
                        dateList.add(current.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                        current = current.plusDays(1);
                    }
                }
            } else {
                // 单日期格式: 2025-06-18
                LocalDate.parse(dateStr.trim(), DateTimeFormatter.ofPattern("yyyy-MM-dd")); // 验证格式
                dateList.add(dateStr.trim());
            }
        } catch (Exception e) {
            // 日期格式错误，返回空列表
            System.err.println("日期格式错误: " + dateStr);
        }
        
        return dateList;
    }

    /**
     * 软删除课程安排
     * 
     * @param scheduleId 课程安排主键
     * @return 结果
     */
    @Override
    public int softDeleteCourseSchedule(Long scheduleId)
    {
        // 先获取原记录
        CourseSchedule courseSchedule = courseScheduleMapper.selectCourseScheduleByScheduleId(scheduleId);
        if (courseSchedule != null) {
            // 设置为删除状态并更新时间
            courseSchedule.setStatus("0");
            courseSchedule.setUpdTime(getCurrentTimeString());
            // 直接调用mapper方法，避免触发调课记录逻辑
            return courseScheduleMapper.updateCourseSchedule(courseSchedule);
        }
        return 0;
    }

    /**
     * 一键加课
     * 
     * @param oneClickDto 一键加课参数
     * @return 添加的课程数量
     */
    @Override
    public int oneClickAddSchedule(OneClickAddScheduleDto oneClickDto) {
        // 1. 参数验证和lessonId处理
        if (oneClickDto.getClaId() == null) {
            throw new RuntimeException("班级ID不能为空");
        }
        
        // 如果lessonId为null，尝试从现有课程安排中获取
        if (oneClickDto.getLessonId() == null) {
            Long lessonId = findLessonIdFromExistingSchedules(oneClickDto.getClaId());
            if (lessonId == null) {
                throw new RuntimeException("无法找到班级对应的课程ID，请确保班级已有课程安排");
            }
            oneClickDto.setLessonId(lessonId);
        }
        
        // 2. 获取班级信息，检查开班时间、毕业时间和总课时
        CourseCla courseCla = courseClaMapper.selectCourseClaByClaId(oneClickDto.getClaId().intValue());
        if (courseCla == null) {
            throw new RuntimeException("班级信息不存在");
        }

        // 2. 检查班级状态
        if (courseCla.getClaStatus() != null && courseCla.getClaStatus() == 1) {
            throw new RuntimeException("班级已毕业，无法添加课程");
        }

        // 3. 解析开班时间和毕业时间
        LocalDate startDate = parseDate(courseCla.getStartTime());
        LocalDate endDate = parseDate(courseCla.getEndTime());
        
        if (startDate == null || endDate == null) {
            throw new RuntimeException("班级开班时间或毕业时间格式错误");
        }

        // 4. 获取已有的课程安排，分析课程模式
        List<CourseSchedule> existingSchedules = courseScheduleMapper.selectCourseScheduleByClaId(oneClickDto.getClaId());
        
        // 过滤出状态为1（正常）且scheduleType为1或2的课程作为模板
        List<CourseSchedule> validSchedules = new ArrayList<>();
        for (CourseSchedule schedule : existingSchedules) {
            if ("1".equals(schedule.getStatus()) && 
                ("1".equals(schedule.getScheduleType()) || "2".equals(schedule.getScheduleType()))) {
                validSchedules.add(schedule);
            }
        }

        if (validSchedules.isEmpty()) {
            throw new RuntimeException("请先添加一些课程安排作为模板，然后再使用一键加课功能");
        }

        // 5. 分析现有课程的周模式（周几上课，什么时间）
        Map<DayOfWeek, List<String>> weeklyPattern = analyzeWeeklyPattern(validSchedules);
        
        if (weeklyPattern.isEmpty()) {
            throw new RuntimeException("无法分析出有效的周课程模式");
        }

        // 输出分析到的课程模式，便于调试
        System.out.println("分析到的周课程模式：");
        for (Map.Entry<DayOfWeek, List<String>> entry : weeklyPattern.entrySet()) {
            System.out.print("  " + entry.getKey() + ": ");
            double totalHoursPerDay = 0.0;
            for (String timePeriod : entry.getValue()) {
                double hours = calculateHoursFromTimePeriod(timePeriod);
                totalHoursPerDay += hours;
                System.out.print(timePeriod + "(1课时) ");
            }
            System.out.println("| 每天总计: " + totalHoursPerDay + "课时");
        }

        // 6. 检查课时限制
        Long totalClassHours = courseCla.getTotalNum();
        
        if (totalClassHours == null || totalClassHours <= 0) {
            throw new RuntimeException("班级总课时设置错误");
        }

        // 7. 计算已安排的课时
        double scheduledClassHours = 0.0;
        for (CourseSchedule schedule : existingSchedules) {
            if ("1".equals(schedule.getStatus())) { // 只统计正常状态的课程
                scheduledClassHours += 1.0; // 每个课程安排固定1课时
            }
        }
        
        // 8. 计算剩余课时
        double remainingClassHours = totalClassHours - scheduledClassHours;
        if (remainingClassHours <= 0) {
            throw new RuntimeException("班级课时已满，无法添加更多课程。总课时:" + totalClassHours + "课时，已安排:" + scheduledClassHours + "课时");
        }
        
        System.out.println("课时统计：总课时=" + totalClassHours + "课时，已安排=" + scheduledClassHours + "课时，剩余=" + remainingClassHours + "课时");
        


        // 9. 生成后续的课程安排
        List<CourseSchedule> newSchedules = generateSchedulesByPattern(
            weeklyPattern, 
            startDate, 
            endDate, 
            oneClickDto, 
            validSchedules,
            remainingClassHours
        );

        // 10. 批量插入新的课程安排
        if (!newSchedules.isEmpty()) {
            System.out.println("准备插入" + newSchedules.size() + "个新课程安排");
            for (CourseSchedule schedule : newSchedules) {
                System.out.println("  - " + schedule.getSpecificDate() + " " + schedule.getTimePeriod());
            }
            int result = courseScheduleMapper.batchInsertCourseSchedule(newSchedules);
            System.out.println("实际插入了" + result + "个课程安排");
            return result;
        }

        return 0;
    }

    /**
     * 从现有课程安排中查找lessonId
     * 
     * @param claId 班级ID
     * @return lessonId，如果找不到则返回null
     */
    private Long findLessonIdFromExistingSchedules(Long claId) {
        // 查询该班级的现有课程安排
        List<CourseSchedule> existingSchedules = courseScheduleMapper.selectCourseScheduleByClaId(claId);
        
        if (existingSchedules != null && !existingSchedules.isEmpty()) {
            // 从现有课程安排中获取lessonId
            for (CourseSchedule schedule : existingSchedules) {
                if (schedule.getLessonId() != null) {
                    return schedule.getLessonId();
                }
            }
        }
        
        return null;
    }

    /**
     * 分析现有课程的周模式
     * 
     * @param schedules 现有课程安排
     * @return 周模式映射（周几 -> 时间段列表）
     */
    private Map<DayOfWeek, List<String>> analyzeWeeklyPattern(List<CourseSchedule> schedules) {
        Map<DayOfWeek, List<String>> pattern = new HashMap<>();
        
        for (CourseSchedule schedule : schedules) {
            if (schedule.getSpecificDate() != null && schedule.getTimePeriod() != null) {
                LocalDate date = parseDate(schedule.getSpecificDate());
                if (date != null) {
                    DayOfWeek dayOfWeek = date.getDayOfWeek();
                    
                    // 获取该星期几的时间段列表，如果不存在则创建新列表
                    List<String> timePeriods = pattern.computeIfAbsent(dayOfWeek, k -> new ArrayList<>());
                    
                    // 如果该时间段还没有添加过，则添加
                    if (!timePeriods.contains(schedule.getTimePeriod())) {
                        timePeriods.add(schedule.getTimePeriod());
                    }
                }
            }
        }
        
        return pattern;
    }

    /**
     * 从时间段字符串计算课时数
     * 每个时间段固定算1课时
     * 
     * @param timePeriod 时间段，格式如 "09:00-12:00"
     * @return 课时数，固定返回1
     */
    private double calculateHoursFromTimePeriod(String timePeriod) {
        if (timePeriod == null || timePeriod.trim().isEmpty()) {
            return 0;
        }
        
        // 简单验证时间段格式是否有效
        if (timePeriod.contains("-")) {
            return 1.0; // 每个时间段固定1课时
        }
        
        return 0;
    }

    /**
     * 根据模式生成后续的课程安排
     * 
     * @param weeklyPattern 周模式
     * @param classStartDate 开班时间
     * @param classEndDate 毕业时间
     * @param oneClickDto 参数
     * @param existingSchedules 已有课程安排
     * @param remainingClassHours 剩余课时数
     * @return 新的课程安排列表
     */
    private List<CourseSchedule> generateSchedulesByPattern(
            Map<DayOfWeek, List<String>> weeklyPattern,
            LocalDate classStartDate,
            LocalDate classEndDate,
            OneClickAddScheduleDto oneClickDto,
            List<CourseSchedule> existingSchedules,
            double remainingClassHours) {
        
        List<CourseSchedule> newSchedules = new ArrayList<>();
        
        // 获取已有课程的最后日期，作为起始点
        LocalDate lastCourseDate = getLastCourseDate(existingSchedules);
        LocalDate startGenerateDate = lastCourseDate != null ? lastCourseDate.plusDays(1) : classStartDate;
        
        // 确保生成起始日期不早于开班时间
        if (startGenerateDate.isBefore(classStartDate)) {
            startGenerateDate = classStartDate;
        }

        double addedClassHours = 0.0;
        int addedClassCount = 0;
        LocalDate currentDate = startGenerateDate;

        System.out.println("开始生成课程：从" + startGenerateDate + "到" + classEndDate + "，剩余课时" + remainingClassHours + "课时");
        
        // 循环生成课程，直到毕业时间（课时限制在内层循环中检查）
        while (currentDate.isBefore(classEndDate.plusDays(1))) {
            System.out.println("检查日期：" + currentDate + "，已生成课时：" + addedClassHours + "/" + remainingClassHours + "课时");
            DayOfWeek dayOfWeek = currentDate.getDayOfWeek();
            
            // 如果当前日期的星期几在模式中，生成该日的时间段课程
            if (weeklyPattern.containsKey(dayOfWeek)) {
                List<String> timePeriodsForDay = weeklyPattern.get(dayOfWeek);
                
                // 为该日期的每个时间段生成课程
                for (String timePeriod : timePeriodsForDay) {
                    // 每个时间段固定1课时
                    double currentTimePeriodHours = 1.0;
                    
                    // 计算还需要多少课时才能用完
                    double stillNeedHours = remainingClassHours - addedClassHours;
                    
                    // 如果剩余课时不足1课时，跳过这个时间段
                    if (stillNeedHours < 1.0) {
                        System.out.println("剩余课时不足1课时(" + stillNeedHours + "h < 1h)，跳过时间段：" + timePeriod);
                        continue;
                    }
                
                    // 检查是否已存在该日期和时间段的课程
                    if (!isDateTimeConflict(currentDate, timePeriod, existingSchedules, newSchedules)) {
                        CourseSchedule newSchedule = new CourseSchedule();
                        newSchedule.setLessonId(oneClickDto.getLessonId());
                        newSchedule.setClaId(oneClickDto.getClaId());
                        newSchedule.setScheduleType(CourseScheduleConstants.ScheduleType.ONE_CLICK_ADD);
                        newSchedule.setSpecificDate(currentDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                        newSchedule.setTimePeriod(timePeriod);
                        newSchedule.setStatus(CourseScheduleConstants.Status.ACTIVE);
                        
                        // 设置创建和更新时间
                        String currentTime = getCurrentTimeString();
                        newSchedule.setCreTime(currentTime);
                        newSchedule.setUpdTime(currentTime);
                        
                        newSchedules.add(newSchedule);
                        addedClassHours += currentTimePeriodHours; // 固定加1课时
                        addedClassCount++;
                        
                        System.out.println("生成第" + addedClassCount + "节课：" + currentDate + " " + timePeriod + 
                                         " (1课时)，累计课时：" + addedClassHours + "课时");
                        
                        // 检查是否已达到课时限制，如果是则停止生成
                        if (addedClassHours >= remainingClassHours) {
                            System.out.println("已达到课时限制，停止生成课程");
                            return newSchedules; // 直接返回，不再继续生成
                        }
                    }
                }
            }
            
            currentDate = currentDate.plusDays(1);
        }
        
        System.out.println("课程生成完成，总共生成了" + addedClassCount + "节课，" + addedClassHours + "课时");
        
        return newSchedules;
    }

    /**
     * 获取已有课程的最后日期
     * 
     * @param schedules 已有课程安排
     * @return 最后课程日期
     */
    private LocalDate getLastCourseDate(List<CourseSchedule> schedules) {
        LocalDate lastDate = null;
        
        for (CourseSchedule schedule : schedules) {
            if (schedule.getSpecificDate() != null) {
                LocalDate date = parseDate(schedule.getSpecificDate());
                if (date != null && (lastDate == null || date.isAfter(lastDate))) {
                    lastDate = date;
                }
            }
        }
        
        return lastDate;
    }

    /**
     * 检查日期是否冲突
     * 
     * @param date 要检查的日期
     * @param existingSchedules 已有课程安排
     * @param newSchedules 新生成的课程安排
     * @return 是否冲突
     */
    private boolean isDateConflict(LocalDate date, List<CourseSchedule> existingSchedules, List<CourseSchedule> newSchedules) {
        String dateStr = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        
        // 检查与已有课程的冲突
        for (CourseSchedule schedule : existingSchedules) {
            if (dateStr.equals(schedule.getSpecificDate()) && "1".equals(schedule.getStatus())) {
                return true;
            }
        }
        
        // 检查与新生成课程的冲突
        for (CourseSchedule schedule : newSchedules) {
            if (dateStr.equals(schedule.getSpecificDate())) {
                return true;
            }
        }
        
        return false;
    }

    /**
     * 检查日期和时间段是否冲突
     * 
     * @param date 要检查的日期
     * @param timePeriod 要检查的时间段
     * @param existingSchedules 已有课程安排
     * @param newSchedules 新生成的课程安排
     * @return 是否冲突
     */
    private boolean isDateTimeConflict(LocalDate date, String timePeriod, List<CourseSchedule> existingSchedules, List<CourseSchedule> newSchedules) {
        String dateStr = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        
        // 检查与已有课程的冲突
        for (CourseSchedule schedule : existingSchedules) {
            if (dateStr.equals(schedule.getSpecificDate()) && 
                timePeriod.equals(schedule.getTimePeriod()) && 
                "1".equals(schedule.getStatus())) {
                return true;
            }
        }
        
        // 检查与新生成课程的冲突
        for (CourseSchedule schedule : newSchedules) {
            if (dateStr.equals(schedule.getSpecificDate()) && 
                timePeriod.equals(schedule.getTimePeriod())) {
                return true;
            }
        }
        
        return false;
    }

    /**
     * 解析日期字符串
     * 
     * @param dateStr 日期字符串
     * @return LocalDate对象
     */
    private LocalDate parseDate(String dateStr) {
        if (dateStr == null || dateStr.trim().isEmpty()) {
            return null;
        }
        
        try {
            return LocalDate.parse(dateStr.trim(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * 记录调课信息
     * 
     * @param newCourseSchedule 新的课程安排（要更新的）
     */
    private void recordCourseSwitch(CourseSchedule newCourseSchedule) {
        try {
            // 获取原课程安排信息
            CourseSchedule originalSchedule = courseScheduleMapper.selectCourseScheduleByScheduleId(newCourseSchedule.getScheduleId());
            if (originalSchedule == null) {
                System.err.println("无法获取原课程安排信息，scheduleId: " + newCourseSchedule.getScheduleId());
                return;
            }
            
            // 如果是删除操作（状态变为0），不记录调课信息
            if ("0".equals(newCourseSchedule.getStatus())) {
                System.out.println("课程删除操作，无需记录调课信息，scheduleId: " + newCourseSchedule.getScheduleId());
                return;
            }
            
            // 获取班级信息（用于获取校区id和courseId）
            CourseCla courseCla = courseClaMapper.selectCourseClaByClaId(originalSchedule.getClaId().intValue());
            if (courseCla == null) {
                System.err.println("无法获取班级信息，claId: " + originalSchedule.getClaId());
                return;
            }
            
            // 通过claId获取courseLesson信息，进而获取courseId
            com.ruoyi.course.domain.CourseLesson courseLesson = courseLessonMapper.selectCourseLessonByClaId(String.valueOf(originalSchedule.getClaId()));
            
            if (courseLesson == null || courseLesson.getCourseId() == null) {
                System.err.println("无法获取课程信息，claId: " + originalSchedule.getClaId());
                return;
            }
            
            // 生成关联id（使用时间戳确保唯一性）
            String relationId = String.valueOf(System.currentTimeMillis());
            String currentTime = getCurrentTimeString(); // 完整格式：yyyy-MM-dd HH:mm:ss
            
            // 创建修改前的记录
            CourseSwitch beforeSwitch = new CourseSwitch();
            beforeSwitch.setCampusId(courseCla.getCampusId());
            beforeSwitch.setLessonId(courseLesson.getCourseId()); // 存储courseId而不是lessonId
            beforeSwitch.setClaId(originalSchedule.getClaId().intValue());
            beforeSwitch.setWeekDay(originalSchedule.getSpecificDate()); // 日期存入weekDay
            beforeSwitch.setTimeFrame(originalSchedule.getTimePeriod()); // 时间段存入timeFrame
            beforeSwitch.setCreTime(currentTime);
            beforeSwitch.setUpdTime(currentTime);
            beforeSwitch.setEmpty1(relationId); // 用于关联修改前后的记录
            beforeSwitch.setEmpty2("before"); // 标识这是修改前的记录
            beforeSwitch.setEmpty3(null); // 确保状态为正常
            
            // 创建修改后的记录
            CourseSwitch afterSwitch = new CourseSwitch();
            afterSwitch.setCampusId(courseCla.getCampusId());
            afterSwitch.setLessonId(courseLesson.getCourseId()); // 存储courseId而不是lessonId
            afterSwitch.setClaId(originalSchedule.getClaId().intValue());
            afterSwitch.setWeekDay(newCourseSchedule.getSpecificDate() != null ? 
                                 newCourseSchedule.getSpecificDate() : originalSchedule.getSpecificDate()); // 日期存入weekDay
            afterSwitch.setTimeFrame(newCourseSchedule.getTimePeriod() != null ? 
                                   newCourseSchedule.getTimePeriod() : originalSchedule.getTimePeriod()); // 时间段存入timeFrame
            afterSwitch.setCreTime(currentTime);
            afterSwitch.setUpdTime(currentTime);
            afterSwitch.setEmpty1(relationId); // 用于关联修改前后的记录
            afterSwitch.setEmpty2("after"); // 标识这是修改后的记录
            afterSwitch.setEmpty3(null); // 确保状态为正常
            
            // 检查是否确实有修改（只有时间段或日期有变化才记录）
            boolean hasTimeChange = (newCourseSchedule.getTimePeriod() != null && 
                                   !originalSchedule.getTimePeriod().equals(newCourseSchedule.getTimePeriod()));
            boolean hasDateChange = (newCourseSchedule.getSpecificDate() != null && 
                                   !originalSchedule.getSpecificDate().equals(newCourseSchedule.getSpecificDate()));
            
            if (hasTimeChange || hasDateChange) {
                // 插入修改前的记录
                courseSwitchMapper.insertCourseSwitch(beforeSwitch);
                String changeType = hasDateChange ? "日期变化" : "时间段变化";
                System.out.println("记录调课信息（修改前）- " + changeType + "：" + beforeSwitch.getWeekDay() + " " + beforeSwitch.getTimeFrame());
                
                // 插入修改后的记录
                courseSwitchMapper.insertCourseSwitch(afterSwitch);
                System.out.println("记录调课信息（修改后）- " + changeType + "：" + afterSwitch.getWeekDay() + " " + afterSwitch.getTimeFrame());
                System.out.println("调课记录关联ID：" + relationId);
                
                // 额外记录变化详情
                if (hasDateChange) {
                    System.out.println("日期变化：" + originalSchedule.getSpecificDate() + " -> " + afterSwitch.getWeekDay());
                }
                if (hasTimeChange) {
                    System.out.println("时间变化：" + originalSchedule.getTimePeriod() + " -> " + afterSwitch.getTimeFrame());
                }
            } else {
                System.out.println("课程时间无变化，无需记录调课信息");
            }
            
        } catch (Exception e) {
            System.err.println("记录调课信息失败: " + e.getMessage());
            e.printStackTrace();
            // 不抛出异常，避免影响主要的更新操作
        }
    }
}
